package com.py.credit.service.impl;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.NameValuePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.py.credit.constant.SubjectTypConstant;
import com.py.credit.dao.DataCoverageDao;
import com.py.credit.dao.HomeCreditMapDao;
import com.py.credit.entity.CoverageData;
import com.py.credit.entity.DataTableEntity;
import com.py.credit.entity.Table;
import com.py.credit.service.HomeCreditMapService;
import com.py.credit.utils.LonAndLatUtil;
import com.py.credit.utils.NumberUtils;
import com.py.credit.utils.PercentUtil;
import com.py.credit.utils.ThreadMapCallable;
import com.py.framework.core.common.Page;

@Service
public class HomeCreditMapServiceImpl implements HomeCreditMapService{

	@Autowired
	private HomeCreditMapDao homeCreditMapDao;
	@Autowired
	private DataCoverageDao dataCoverageDao;
	
	@Override
	@Transactional
	public void updateLonAndLat(String url,String mapKey) throws InterruptedException, ExecutionException {
		// TODO Auto-generated method stub
		if (url == null || "".equals(url)) {
			url = "http://api.tianditu.gov.cn/geocoder";
		}
		long aa=System.currentTimeMillis();
		List<Map> listOfEmptyAdd = homeCreditMapDao.queryListOfEmptyAdd();
		List<Map> target =new ArrayList<Map>();
		long bb=System.currentTimeMillis();
		System.out.println(aa-bb);
		int poolSize=50;
		ExecutorService es = Executors.newFixedThreadPool(poolSize);
		List<Future<List<Map<String,String>>>> listFuture = new ArrayList<Future<List<Map<String,String>>>>();
		List<List<Map>> listE=averageAssign(listOfEmptyAdd, poolSize);
		for (int i = 0; i < poolSize; i++) {
			Callable c = new ThreadMapCallable(listE.get(i),url,mapKey);
			Future<List<Map<String,String>>> f = es.submit(c);
			listFuture.add(f);
		}
		es.shutdown();
		long b=System.currentTimeMillis();
		for (Future f : listFuture) {
			// 从Future对象上获取任务的返回值，并输出到控制台
			List<Map>  lm= (List<Map>) f.get();
			target.addAll(lm);
	    }
		long a=System.currentTimeMillis();
		System.out.println(a-b);
		//target.addAll((List<Map>)call(listOfEmptyAdd,url,mapKey));
		if(target!=null&&target.size()>0){
			homeCreditMapDao.updateEmptyAddAll(target);
		}
	}
	
	@Override
	@Transactional
	public void updateLonAndLatPer(String url,String mapKey) throws InterruptedException, ExecutionException {
		// TODO Auto-generated method stub
		if (url == null || "".equals(url)) {
			url = "http://api.tianditu.gov.cn/geocoder";
		}
		long aa=System.currentTimeMillis();
		List<Map> listOfEmptyAdd = homeCreditMapDao.queryListOfEmptyAddPer();
		List<Map> target =new ArrayList<Map>();
		long bb=System.currentTimeMillis();
		System.out.println(aa-bb);
		int poolSize=50;
		ExecutorService es = Executors.newFixedThreadPool(poolSize);
		List<Future<List<Map<String,String>>>> listFuture = new ArrayList<Future<List<Map<String,String>>>>();
		List<List<Map>> listE=averageAssign(listOfEmptyAdd, poolSize);
		for (int i = 0; i < poolSize; i++) {
			Callable c = new ThreadMapCallable(listE.get(i),url,mapKey);
			Future<List<Map<String,String>>> f = es.submit(c);
			listFuture.add(f);
		}
		es.shutdown();
		long b=System.currentTimeMillis();
		for (Future f : listFuture) {
			// 从Future对象上获取任务的返回值，并输出到控制台
			List<Map>  lm= (List<Map>) f.get();
			target.addAll(lm);
	    }
		long a=System.currentTimeMillis();
		System.out.println(a-b);
		//target.addAll((List<Map>)call(listOfEmptyAdd,url,mapKey));
		if(target!=null&&target.size()>0){
			homeCreditMapDao.updateEmptyAddAllPer(target);
		}
	}
	
	@Override
	public List<Map> queryAllAreaCodes() {
		return homeCreditMapDao.queryAllAreaCodes();
	}
	
	@Override
	public List<Map<String, String>> getMapData(String type,String mainType,String deptid) {
		List<Map<String, String>> data = homeCreditMapDao.getMapData(type,mainType,deptid);
		for (Map<String, String> map : data) {
			List<String> asList = Arrays.asList(map.get("relateIndex").split(","));
			if(asList != null && asList.size()>0) {
				String name = homeCreditMapDao.selectIndexName(asList);
				map.put("IndexName", name);	
			}
		}
		return data;
	}
	
	@Override
	public List<Map<String, String>> countByType() {
		List<Map<String, String>> data = homeCreditMapDao.countByType();
		StringBuffer sb = new StringBuffer();
		for (Map<String, String> map : data) {
			sb.append(map.get("type"));
		}
		if(sb.indexOf("1") == -1) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("type", "1");
			map.put("count", "0");
			data.add(map);
			}
			if(sb.indexOf("2") == -1) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("type", "2");
			map.put("count", "0");
			data.add(map);
			}
			if(sb.indexOf("3") == -1) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("type", "3");
			map.put("count", "0");
			data.add(map);
			}
			if(sb.indexOf("4") == -1) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("type", "4");
			map.put("count", "0");
			data.add(map);	
			}
		return data;
	}
	
	
	 @Override
	    @Transactional(rollbackFor = Exception.class)
	    public void insertData() {
	        List<String> list = dataCoverageDao.selectTableName();
	        Integer molecule = 0;
	        Integer denominator = homeCreditMapDao.bodyCorporateCount();
	        if (!CollectionUtils.isEmpty(list)) {
	            //查询所有表去重后归集数据
	            molecule = dataCoverageDao.selectDataCount(list);
	        }
	        //计算整体覆盖率
	        String percent = PercentUtil.getPercent(molecule, denominator);
	        CoverageData col = new CoverageData();
	        col.setEntityCount(denominator);
	        col.setI(molecule);
	        col.setPercent(percent);
	        //删除原数据
	        dataCoverageDao.deleteDataCount();
	        //插入数据
	        dataCoverageDao.insertDataCount(col);

	        try {
	            //获取全部的表信息
	            List<Table> tableList = dataCoverageDao.selectTable();
	            List<DataTableEntity> dataTableEntities = new ArrayList<>();
	            if (!CollectionUtils.isEmpty(tableList)) {
	                for (Table table : tableList) {
	                    String tableName = "t_" + table.getResourceId();
	                    //获取单个资源信息总数
	                    int count = dataCoverageDao.getAllDataCount(tableName);
	                    //获取单个资源已归集去重后总数
	                    int disCount = dataCoverageDao.getDisDataCount(tableName);
	                    percent = PercentUtil.getPercent(disCount, count);
	                    DataTableEntity dataTableEntity = new DataTableEntity();
	                    dataTableEntity.setTableName(table.getResourceTitle());
	                    dataTableEntity.setPerCent(percent);
	                    dataTableEntity.setAlsoEntityCount(molecule);
	                    dataTableEntity.setTableId(table.getTableId());
	                    dataTableEntity.setTableCount(count);
	                    dataTableEntity.setTableEntityCount(disCount);
	                    dataTableEntities.add(dataTableEntity);
	                }
	            }

	            dataCoverageDao.deleteColumnTable();
	            if (dataTableEntities.size() > 0) {
	                dataCoverageDao.insertColumnTable(dataTableEntities);
	            }
	        } catch (Exception e) {
	            System.out.println(e.getMessage());
	        }
	    }
	 
	 @Override
		public Integer selectFrCount() {
			return dataCoverageDao.bodyCorporateCount();
		}
	
	 @Override
		public List<Map<String, String>> getSubjectLsitForPage(String kId, String input, Page page) {

			String whereSql = null;

			List<Map<String, String>> list = new ArrayList<>();

			if (SubjectTypConstant.SUJECT_TYPE_FR.equals(kId)) {

				whereSql = "A000001 LIKE '%" + input + "%' OR A000002 = '" + input + "'";

			} else if (SubjectTypConstant.SUJECT_TYPE_ZRR.equals(kId)) {

				whereSql = "B000001 LIKE '%" + input + "%' OR B000002 = '" + input + "'";

			} else if (SubjectTypConstant.SUJECT_TYPE_FQYFR.equals(kId)) {

				whereSql = "C000001 LIKE '%" + input + "%' OR C000002 = '" + input + "'";
			}

			if (whereSql != null) {

				list = homeCreditMapDao.selectUniqueByKeyForPage(kId, whereSql, page);

//				if (!CollectionUtils.isEmpty(list) && SubjectTypConstant.SUJECT_TYPE_ZRR.equals(kId)) {
//
//					for (Map<String, String> map : list) {
//
//						String idEncrypt = NumberUtils.idEncrypt(map.get("B000002"));
//
//						map.put("B000002", idEncrypt);
//
//					}
//				}

			}

			return list;
		}
	 
	 @Override
		public List<Map<String, Object>> getWarnData(String id, String tybm) {
		 StringBuffer tableCode = new StringBuffer();
		 String table = homeCreditMapDao.selectTableCode(id);
		 tableCode.append("t_")
		 .append(table);
			return homeCreditMapDao.selectDataById(tableCode.toString(), tybm);
		}

	 
	public List<Map> call(List<Map> listE,String url,String mapKey) {
		if(StringUtils.isBlank(url)){
			url = "http://api.tianditu.gov.cn/geocoder";
		}
		if (listE != null && listE.size() > 0) {
			for (int i = 0; i < listE.size(); i++) {
				Map m = listE.get(i);
			    try{
				    String urlI=url;
					String address = m.get("zs").toString();
					List<NameValuePair> list = new ArrayList<NameValuePair>();
				/*	list.add(new BasicNameValuePair("ds", "{\"keyWord\":\"" + address + "\"}"));
					list.add(new BasicNameValuePair("tk", mapKey));*/
					String qt=URLEncoder.encode("\"","utf-8");
					String le=URLEncoder.encode("{","utf-8");
					String ri=URLEncoder.encode("}","utf-8");
					String par="?ds={\"keyWord\":\"" + address + "\"}";
					par=par.replaceAll("\"", qt).replaceAll("\\{", le).replaceAll("}", ri).replaceAll("#", "");
					urlI+=par;
					urlI+="&&tk="+mapKey;
					System.out.println(urlI);
					String content = LonAndLatUtil.UrlConn(urlI, list);
					if (content != null && !"".equals(content)) {
						System.out.println(content);
						/*JSONObject jsStr = JSONObject.parseObject(content);
						String detail = jsStr.get("location") == null ? "" : jsStr.get("location").toString();
						JSONObject detailJson = JSONObject.parseObject(detail);
						if (detailJson != null && !detailJson.equals("")) {
							creditMapDao.updateEmptyAdd(detailJson.get("lon").toString(), detailJson.get("lat").toString(),
									m.get("tybm").toString());
							listE.get(i).put("lon", detailJson.get("lon").toString());
							listE.get(i).put("lat", detailJson.get("lat").toString());
						}*/
					}

			  }catch(Exception e){
				  System.out.println(e.getMessage()+m.toString());
			  }
				
			}
		}
		return listE;
	}
	
	/**
	 * 将一组数据平均分成n组
	 *
	 * @param source
	 *            要分组的数据源
	 * @param n
	 *            平均分成n组
	 * @param <T>
	 * @return
	 */
	public static <T> List<List<T>> averageAssign(List<T> source, int n) {
		List<List<T>> result = new ArrayList<List<T>>();
		int remainder = source.size() % n; // (先计算出余数)
		int number = source.size() / n; // 然后是商
		int offset = 0;// 偏移量
		for (int i = 0; i < n; i++) {
			List<T> value = null;
			if (remainder > 0) {
				value = source.subList(i * number + offset, (i + 1) * number + offset + 1);
				remainder--;
				offset++;
			} else {
				value = source.subList(i * number + offset, (i + 1) * number + offset);
			}
			result.add(value);
		}
		return result;
	}

}
